#region Usings
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

using Import.Exceptions;
#endregion

namespace Bk.Import.CashOrganizer
{
    public class CoInfoBlocksReader
    {
        #region Instance Methods
        public List<CoInfoBlock> Read(Stream stream)
        {
            List<CoInfoBlock> result = new List<CoInfoBlock>();

            using (StreamReader streamReader = new StreamReader(stream, Encoding.GetEncoding(1251)))
            {
                CoInfoBlock coInfoBlock = null;
                while (!streamReader.EndOfStream)
                {
                    string str = streamReader.ReadLine();
                    if (!string.IsNullOrEmpty(str))
                    {
                        if (coInfoBlock == null)
                        {
                            coInfoBlock = new CoInfoBlock();
                        }

                        if (str != CoConstants.INFO_BLOCK_SEPARATOR)
                        {
                            coInfoBlock.Add(str);
                        }
                        else
                        {
                            result.Add(DoCreateInfoBlock(coInfoBlock, result.Count > 0 ? result[result.Count - 1] : null));
                            coInfoBlock = null;
                        }
                    }
                }

                if ((coInfoBlock != null) && !coInfoBlock.IsEmpty)
                {
                    result.Add(coInfoBlock);
                }
            }
            return result;
        }

        public List<CoInfoBlock> Read(string fileName)
        {
            using (FileStream fileStream = File.OpenRead(fileName))
            {
                return Read(fileStream);
            }
        }

        private CoInfoBlock DoCreateInfoBlock(CoInfoBlock infoBlock, CoInfoBlock currentBlock)
        {
            if (infoBlock.BlockType.HasValue)
            {
                switch (infoBlock.BlockType.Value)
                {
                    case CoInfoBlockType.Account:
                        return new CoAccount(infoBlock);
                    case CoInfoBlockType.TypeBank:
                        return new CoTransaction(infoBlock);
                    default:
                        throw new NotSupportedException();
                }
            }

            if (currentBlock != null)
            {
                CoInfoBlock newInfoBlock = new CoInfoBlock(infoBlock, currentBlock.BlockType.Value);
                return DoCreateInfoBlock(newInfoBlock, null);
            }

            throw new CanNotDefineTypeOfInfo();
        }
        #endregion
    }
}